/*
 * webstartpoint: com.ctvit.framework.flex.SpringLoginCommand.java Create On 2008-12-3 ����05:59:29 By Q-Wang
 * $Header: /home/cvsroot/ctvit/messgeCenter/src/com/ctvit/framework/flex/SpringLoginCommand.java,v 1.1 2015/12/18 01:15:48 yushihao Exp $
 */
package com.ctvit.framework.flex;

import java.security.Principal;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;

import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.support.WebApplicationContextUtils;

import flex.messaging.FlexContext;
import flex.messaging.io.MessageIOConstants;
import flex.messaging.security.LoginCommand;

/**
 * @author Q-Wang
 * 
 */
public class SpringLoginCommand implements LoginCommand {

	private AuthenticationManager authenticationManager;

	/**
	 * @see flex.messaging.security.LoginCommand#doAuthentication(java.lang.String,
	 *      java.lang.Object)
	 */
	public Principal doAuthentication(String username, Object credentials) {
		String password = extractPassword(credentials);
		Authentication authentication = new UsernamePasswordAuthenticationToken(username,
				password);
		try {
			if (authenticationManager == null) {
				authenticationManager = (AuthenticationManager) WebApplicationContextUtils
						.getRequiredWebApplicationContext(
								FlexContext.getServletContext()).getBean(
								"authenticationManager");
			}
			authentication = authenticationManager.authenticate(authentication);
			SecurityContextHolder.getContext()
					.setAuthentication(authentication);
		} catch (AuthenticationException ignore) {
			ignore.printStackTrace();
		} catch (Exception ignore) {
			ignore.printStackTrace();
		}

		if (authentication.isAuthenticated()) {
			// SecurityContextHolder.getContext().setAuthentication(authentication);
			return authentication;
		}
		return null;
	}

	/**
	 * @see flex.messaging.security.LoginCommand#doAuthorization(java.security.Principal,
	 *      java.util.List)
	 */
	public boolean doAuthorization(Principal principal, List roles) {
		// accessDecisionManager.decide(authentication, object, config);
		return true;
	}

	/**
	 * @see flex.messaging.security.LoginCommand#logout(java.security.Principal)
	 */
	public boolean logout(Principal principal) {
		if (principal instanceof Authentication) {
			((Authentication) principal).setAuthenticated(false);
		}
		FlexContext.getFlexSession().invalidate();
		SecurityContextHolder.clearContext();
		return true;
	}

	/**
	 * @see flex.messaging.security.LoginCommand#start(javax.servlet.ServletConfig)
	 */
	public void start(ServletConfig config) {
		if (authenticationManager == null) {
			ApplicationContext applicationContext = WebApplicationContextUtils
					.getRequiredWebApplicationContext(config
							.getServletContext());
			authenticationManager = (AuthenticationManager) applicationContext
					.getBean("authenticationManager");
		}
	}

	/**
	 * @see flex.messaging.security.LoginCommand#stop()
	 */
	public void stop() {
		authenticationManager = null;
	}

	protected String extractPassword(Object credentials) {
		String password = null;
		if (credentials instanceof String) {
			password = (String) credentials;
		} else if (credentials instanceof Map) {
			password = (String) ((Map) credentials)
					.get(MessageIOConstants.SECURITY_CREDENTIALS);
		}
		return password;
	}
}
